package com.lemurian.bankdata.action.business;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.lemurian.bankdata.dto.LogHelper;
import com.lemurian.bankdata.lite.authentication.BankDataPrincipal;
import com.lemurian.bankdata.lite.enums.UserActivityType;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.Pager;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.lite.utils.GeneralConstant;
import com.lemurian.bankdata.lite.utils.GlobalFunction;
import com.lemurian.bankdata.services.ActivityLogService;
import com.lemurian.bankdata.services.CertificateService;
import com.lemurian.bankdata.services.ClientService;
import com.lemurian.bankdata.services.GroupsService;
import com.lemurian.bankdata.services.UserService;
import com.lemurian.bankdata.utils.BaseAction;
import com.lemurian.entity.Client;
import com.lemurian.entity.User;
import com.opensymphony.xwork2.Preparable;

@SuppressWarnings("serial")
public class PersetujuanKlienAction extends BaseAction implements Preparable {

	private BankDataLogger log = BankDataLogger.getLogger(PersetujuanKlienAction.class.getSimpleName());
	
	private String namaDebitur = "";
	
	
	private Client client = new Client();
	private List<Client> listClient;
	
	private int id = 0;
	
	private User user;
	private BankDataPrincipal principal;
	
	private String[] selectedRows;
	
	private String message = "";
	
	@Autowired private ClientService clientService;
	@Autowired private CertificateService certificateService;
	@Autowired private UserService userService;
	@Autowired private GroupsService groupsService;
	
	@Autowired 
	private ActivityLogService userActivityLogService;
	private LogHelper userActivityLog;

	private Integer acceptedStatus;
	private String tglCekOK = "";
	
	private DateFormat df = new SimpleDateFormat("dd-MM-yyyy");

	private String pendingRemarks = "";
	
	@Override
	public void prepare() throws Exception {
		try {
			principal = (BankDataPrincipal) getSession().get(GeneralConstant.USER_PRINCIPAL);
			user = principal.getUser();
			
			log.sInfo("GOT CLIENT ID [%s]", id);
	        if (id > 0) {
	        	client = clientService.load(id);
	        	log.info("Client found [%s]", client.getDebitur().getName());
	        }
		} catch (NullPointerException npe) {
			npe.printStackTrace();
			log.info("CLIENT IS NULL");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	@SkipValidation
	public String list() {
		log.info(": : : ON PERSETUJUAN KLIEN ");
		setPreviousPage(GeneralConstant.LIST);
		try {
			PartialList<Client> partialList = clientService.findClientForPenandatanganan(getStart(), getCount(),
					getAscDesc().equalsIgnoreCase("desc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "debitur.name") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "debitur.name"),
					namaDebitur != null && !namaDebitur.equalsIgnoreCase("") ? Restrictions.ilike("debitur.name", namaDebitur, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
					acceptedStatus != null ? Restrictions.eq("acceptedStatus", acceptedStatus) : Restrictions.ne("id", new Integer(-1))
                    );
			
            listClient = partialList.getList();
            log.sInfo("found [%s] listClient", listClient.size());
            
            setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));

            partialList = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
        setMappedRequest(GeneralConstant.SAVE);
        return SUCCESS;
	}


	@Override
	public String save() {
		log.info("ON Saving Client for Approval");
		try {
			log.info("Tanggal Cek OK      : " + tglCekOK);
			log.info("Accepted Status     : " + acceptedStatus);
			log.info("Pending Remarks     : " + pendingRemarks);
			client.setAcceptedStatus(acceptedStatus);
			client.setPendingRemarks(pendingRemarks);
			if (tglCekOK != null && tglCekOK.length() != 0) {
				client.setCheckDate(df.parse(tglCekOK));
			} else {
				client.setCheckDate(null);
			}
			
			clientService.save(client);
			
			userActivityLog = new LogHelper(user, UserActivityType.APPROVAL_CLIENT_BY_KEPENGURUSAN);
			
            try {
                log.sInfo(" :: User [%s:%s] is successfully approve client with debitur [%s]", user.getId(), user.getName(), client.getDebitur().getName());

                //check if activity is success
                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
                addCustomActionMessage("DATA BERHASIL DISIMPAN");
            } catch (Exception e) {
                log.sInfo(" :: Error was raised when User [%s:%s] approve client with debitur [%s]", user.getId(), user.getName(), client.getDebitur().getName());
                
                //set activity log status into failed
                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
                userActivityLog.setErrorMsg(e.getMessage());
                addCustomActionMessage("Maaf, terjadi kesalahan : " + e.getMessage());
            }
            //save activity log
            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
            userActivityLog.getAdditionalParams().add(client.getDebitur().getName());
            userActivityLogService.saveUserActivity(userActivityLog);
            
			acceptedStatus = null;
		} catch (Exception e) {
			e.printStackTrace();
		}

		//setMappedRequestFullPath("PersetujuanKlienAction_list.do");
		return SUCCESS;
	}
	
	public String decline() {
		return null;
	}

	@Override
	@SkipValidation
	public String add() {
		// TODO Auto-generated method stub
		return null;
	}

	/*@Override
	@SkipValidation
	public String list() {
		log.info("list Sertifikat yang akan dicek");
		setPreviousPage(GeneralConstant.LIST);
		
		try {
			PartialList<Certificate> partialList = sertifikatService.findByCriteria(getStart(), getCount(),
					getAscDesc().equalsIgnoreCase("desc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "name") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "name"),
					namaSertifikat != null && !namaSertifikat.equalsIgnoreCase("") ? Restrictions.ilike("name", namaSertifikat, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
                    nomorSertifikat != null && !nomorSertifikat.equalsIgnoreCase("") ? Restrictions.ilike("number", nomorSertifikat, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1))
                    );

            listSertifikat = partialList.getList();
            log.sInfo("found [%s] sertifikat", listSertifikat.size());
            
            // Collecting AO
            log.sInfo("UserType ID [%s]", UserType.ACCOUNT_OFFICER.id());
            Criterion userTypeAO = Restrictions.eq("userType.id", UserType.ACCOUNT_OFFICER.id());
            Criterion activeUser = Restrictions.eq("status", UserStatus.ACTIVE.code());
            List<User> listAORaw = userService.findByCriteria(Order.asc("name"), userTypeAO, activeUser);
            
            List<String> aoUsernames = new ArrayList<String>();
            for (User ao : listAORaw) {
            	if (aoUsernames.contains(ao.getLoginId())) {
					continue;
				} else {
					aoUsernames.add(ao.getLoginId());
					listAO.add(ao);
				}
			}
            log.sInfo("found [%s] account officer", listAO.size());

            for (Certificate cert : listSertifikat) {
            	PersetujuanKlienHelper pkHelper = new PersetujuanKlienHelper();
            	Client client = klienService.findByCriteria(Restrictions.eq("certificate", cert));
            	if (client != null && client.getCertificate() != null && client.getAccountOfficer() != null) {
            		log.sInfo("Sertifikat [%s] already exist on client table", client.getCertificate().getNumber());
					pkHelper.setSertifikat(client.getCertificate());
					pkHelper.setAo(client.getAccountOfficer());
					listKlien.add(pkHelper);
					continue;
				}
            	log.sInfo("Declined Status [%s]", cert.isDeclined());
            	pkHelper.setSertifikat(cert);
            	pkHelper.setListAO(listAO);
            	
            	listKlien.add(pkHelper);
			}
            log.sInfo("add [%s] klien to table", listKlien.size());

            setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));

            partialList = null;
            
            
		} catch (Exception e) {
			e.printStackTrace();
		}
        setMappedRequest(GeneralConstant.SAVE);
        return SUCCESS;

	}*/

	/*@Override
	public String save() {
		
		try {
			// Set Sertifikat yang didelegasikan
			if (selectedRows == null || selectedRows.length == 0) {
				addCustomActionError("Tentukan sertifikat terlebih dahulu");

	    		setMappedRequestFullPath("/PersetujuanKlienAction_list.do");
	            return GeneralConstant.REDIRECT;
			}
			
			log.sInfo("Total Checked [%s]", selectedRows.length);
			for (int i = 0; i < selectedRows.length; i++) {
				log.sInfo("Rows check [%s]", selectedRows[i]);
				if (selectedAO != null && selectedAO.length != 0) {
					for (int j = 0; j < selectedAO.length; j++) {
						if (selectedAO[j] != null && !selectedAO[j].equalsIgnoreCase("")) {
							String[] value = selectedAO[j].split(";");
							log.sInfo("value ao [%s], value sert [%s]", value[0], value[1]);
							if (value[1].equalsIgnoreCase(selectedRows[i])) {
								log.sInfo("Delegate sertifikat [%s] to AO [%s]", selectedRows[i], value[0]);
								int sertifikatId = Integer.parseInt(GlobalFunction.decodeParameter(selectedRows[i]));
								int aoId = Integer.parseInt(GlobalFunction.decodeParameter(value[0]));
								Certificate sertifikat = sertifikatService.findById(sertifikatId);
								if (sertifikat != null) {
									log.sInfo("found sertifikat with name [%s]", sertifikat.getName());
								}
								User ao = userService.findById(aoId);
								if (sertifikat != null) {
									log.sInfo("found ao with name [%s]", ao.getName());
								}
								
								Client klien = new Client();
								klien.setAccountOfficer(ao);
								klien.setMarketingHead(user);
								klien.setCertificate(sertifikat);
								klien.setCreateDate(new Timestamp(System.currentTimeMillis()));
								try {
									klienService.save(klien);
									
									userActivityLog = new LogHelper(user, UserActivityType.DELEGATE_AO_FOR_CLIENT);
									
						            try {
						                log.sInfo(" :: User [%s:%s] is successfully delegate certificate [%s] to ao [%s]", user.getId(), user.getName(), sertifikat.getName(), ao.getName());

						                //check if activity is success
						                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
						            } catch (Exception e) {
						                log.sInfo(" :: Error was raised when User [%s:%s] delegate certificate [%s] to ao [%s]", user.getId(), user.getName(), sertifikat.getName(), ao.getName());
						                
						                //set activity log status into failed
						                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
						                userActivityLog.setErrorMsg(e.getMessage());
						            }
						            //save activity log
						            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
						            userActivityLog.getAdditionalParams().add(sertifikat.getName());
						            userActivityLog.getAdditionalParams().add(ao.getName());
						            userActivityLogService.saveUserActivity(userActivityLog);
									
								} catch (Exception e) {
									e.printStackTrace();
								    message += "Maaf terjadi kesalahan, message : "+e.getMessage();
						            addCustomActionError(message);
						    		setMappedRequestFullPath("/PersetujuanKlienAction_list.do");
						            return GeneralConstant.REDIRECT;
								}
								message = "Pendelegasi Account Officer berjalan dengan sukses";
					            addCustomActionMessage(message);
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		    message = "Maaf terjadi kesalahan, message : "+e.getMessage();
            addActionError(message);
		}
		setMappedRequestFullPath("/PersetujuanKlienAction_list.do");
        return GeneralConstant.REDIRECT;
        
	}*/
	
	/*public String decline() {
		log.info("decline sertifikat ..");
		try {
			log.sInfo("Total Checked [%s]", selectedRows.length);

			for (int i = 0; i < selectedRows.length; i++) {
				log.sInfo("Rows check [%s]", selectedRows[i]);
				int sertifikatId = Integer.parseInt(GlobalFunction.decodeParameter(selectedRows[i]));
				Certificate sertifikat = sertifikatService.findById(sertifikatId);
				if (sertifikat != null) {
					log.sInfo("found sertifikat with name [%s]", sertifikat.getName());
					sertifikat.setDeclined(true);
					sertifikatService.save(sertifikat);
					
					userActivityLog = new LogHelper(user, UserActivityType.REJECT_AO_FOR_CLIENT);
					
		            try {
		                log.sInfo(" :: User [%s:%s] is successfully reject a certificate [%s]", user.getId(), user.getName(), sertifikat.getName());

		                //check if activity is success
		                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
		            } catch (Exception e) {
		                log.sInfo(" :: Error was raised when User [%s:%s] reject a certificate [%s]", user.getId(), user.getName(), sertifikat.getName());
		                
		                //set activity log status into failed
		                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
		                userActivityLog.setErrorMsg(e.getMessage());
		            }
		            //save activity log
		            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
		            userActivityLog.getAdditionalParams().add(sertifikat.getName());
		            userActivityLogService.saveUserActivity(userActivityLog);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			message += "Maaf terjadi kesalahan, message : "+e.getMessage();
            addCustomActionError(message);
		}
		setMappedRequestFullPath("/PersetujuanKlienAction_list.do");
        return GeneralConstant.REDIRECT;
	}*/

	@Override
	@SkipValidation
	public String edit() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String update() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String detail() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String delete() {
		// TODO Auto-generated method stub
		return null;
	}

	public int getId() {
		return id;
	}

	public void setId(String id) {
		int id_ = 0;
		if(id != null && !id.equalsIgnoreCase("0")) {
			id = GlobalFunction.decodeParameter(id);
	        id_ = Integer.parseInt(id);
		}
        this.id = id_;
	}

	public String getNamaDebitur() {
		return namaDebitur;
	}

	public void setNamaDebitur(String namaDebitur) {
		this.namaDebitur = namaDebitur;
	}

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}

	public List<Client> getListClient() {
		return listClient;
	}

	public void setListClient(List<Client> listClient) {
		this.listClient = listClient;
	}

	public String[] getSelectedRows() {
		return selectedRows;
	}

	public void setSelectedRows(String[] selectedRows) {
		this.selectedRows = selectedRows;
	}

	public Integer getAcceptedStatus() {
		return acceptedStatus;
	}

	public void setAcceptedStatus(Integer acceptedStatus) {
		this.acceptedStatus = acceptedStatus;
	}

	public String getTglCekOK() {
		return tglCekOK;
	}

	public void setTglCekOK(String tglCekOK) {
		this.tglCekOK = tglCekOK;
	}

	public String getPendingRemarks() {
		return pendingRemarks;
	}

	public void setPendingRemarks(String pendingRemarks) {
		this.pendingRemarks = pendingRemarks;
	}

}
